/* components */
import { 
  BaseSelectUserSearchUserGroup, 
  BaseSelectUserUserItems, 
  BaseSelectUserNoDataView,
  BaseSelectUserBackButton,
  BaseSelectUserInfiniteScrollUser,
} from '@src/component/common/BaseSelectUser/components'
/* enum */
import { BaseSelectUserComponentNameEnum, BaseSelectUserFetchDebounceTime, BaseSelectUserSearchMoreTypeEnum, BaseSelectUserSearchMoreTypeNameMap } from '@src/component/common/BaseSelectUser/model'
/* hooks */
import { useBaseSelectUserOptions, useBaseSelectUserSearchMoreUserListParams, useBaseSelectUserTabs, useFetchSearchMoreUserList, useFetchSearchUserList, useSelectUserSearchMoreUserList } from '@src/component/common/BaseSelectUser/hooks'
import { useBaseSelectUserStoreCurrentSearchMoreType, useBaseSelectUserStoreIsSearchOrganizationHasMore, useBaseSelectUserStoreIsSearchSpHasMore, useBaseSelectUserStoreLoadingMap, useBaseSelectUserStoreMarkList, useBaseSelectUserStoreSearchUserListData, useBaseSelectUserStoreUserListMap } from '@src/component/common/BaseSelectUser/store'
/* vue */
// @ts-ignore
import { ComponentInstance, ComponentRenderProxy, computed, defineComponent, PropType, watch } from 'vue'
import { CommonComponentInstance } from '@model/VC'
import { CreateElement } from 'vue'
/* util */
import { debounce } from 'lodash'
import { isEmpty, isFalse } from '@src/util/type'
import { isServiceProviderTab } from '@src/component/common/BaseSelectUser/util'
import { t } from '@src/locales'

export type SearchUserPanelProps = {
  // 搜索关键字
  keyword: string;
  // 是否为多选
  isMulti: boolean;
}

export interface SearchUserPanelSetupState {
  
}

export enum SearchUserPanelEmitEventNameEnum {
  Input = 'input',
}

export type SearchUserPanelInstance = ComponentInstance & SearchUserPanelSetupState
export type SearchUserPanelVM = ComponentRenderProxy<SearchUserPanelProps> & CommonComponentInstance & SearchUserPanelInstance

export default defineComponent({
  name: BaseSelectUserComponentNameEnum.BaseSelectUserSearchUserPanel,
  emits: [
    SearchUserPanelEmitEventNameEnum.Input
  ],
  props: {
    /* 是否为多选状态 */
    isMulti: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    keyword: {
      type: String as PropType<string>,
      default: ''
    }
  },
  setup(props: SearchUserPanelProps, { emit }) {
    
    const { 
      organizationUserList, 
      serviceProviderUserList,
      isOrganizationUserListEmpty,
      isServiceProviderUserListEmpty,
      isOrganizationUserListNotEmpty,
      isServiceProviderUserListNotEmpty,
      setSearchUserListData
    } = useBaseSelectUserStoreSearchUserListData()
    
    const { isCurrentSearchMoreTypeEmpty, isCurrentSearchMoreTypeNotEmpty, currentSearchMoreType, setCurrentSearchMoreType } = useBaseSelectUserStoreCurrentSearchMoreType()
    const { searchLoading, setSearchLoading, clearSearchLoading } = useBaseSelectUserStoreLoadingMap()
    const { searchMoreUserList, isSearchMoreUserListEmpty, setSearchMoreUserList } = useBaseSelectUserStoreUserListMap()
    
    const { addPageNum, resetPageNum } = useBaseSelectUserSearchMoreUserListParams()
    
    const { showDelete, isShowSearchOrganizationUsers, isShowSearchServiceProviderUsers, showTagIfSpUser, showNoDistribute, isAuthKey } = useBaseSelectUserOptions()
    
    const { isLoadmoreNotDisabled, isLoadmoreDisabled } = useSelectUserSearchMoreUserList()
    
    const { isSearchOrganizationHasMore } = useBaseSelectUserStoreIsSearchOrganizationHasMore()
    const { isSearchSpHasMore } = useBaseSelectUserStoreIsSearchSpHasMore()
    
    const { tabs } = useBaseSelectUserTabs()
    
    const fetchSearchMoreUserList = useFetchSearchMoreUserList()
    const fetchSearchUserList = useFetchSearchUserList()
    
    const fetchSearchUserListDebounceHandler = debounce(fetchSearchUserList, BaseSelectUserFetchDebounceTime)
    
    const isShowNotDataView = computed(() => {
      return isFalse(searchLoading.value) && isOrganizationUserListEmpty.value && isServiceProviderUserListEmpty.value
    })
    
    const backButtonName = computed(() => {
      
      if (isCurrentSearchMoreTypeEmpty.value) {
        return undefined
      }
      
      return BaseSelectUserSearchMoreTypeNameMap[currentSearchMoreType.value as unknown as BaseSelectUserSearchMoreTypeEnum]
    })
    
    /** 
     * @description 是否显示搜索更多人员列表无数据页面
     * 1. 更多人员列表为空
     * 2. 且 不在加载状态
    */
    const isShowSearchMoreUserListNotDataView = computed(() => {
      return isSearchMoreUserListEmpty.value && isFalse(searchLoading.value)
    })
    
    /** 
     * @description 是否不显示搜索更多人员列表无数据页面
    */
    const isNotShowSearchMoreUserListNotDataView = computed(() => {
      return isFalse(isShowSearchMoreUserListNotDataView.value)
    })
    
    const isShowSearchOrganizationUserList = computed(() => {
      return isOrganizationUserListNotEmpty.value && isShowSearchOrganizationUsers.value
    })
    
    const isShowSearchServiceProviderUserList = computed(() => {
      return isServiceProviderUserListNotEmpty.value && isShowSearchServiceProviderUsers.value
    })
    
    const resetSearchMoreUserListAndPage = () => {
      resetPageNum()
      setSearchMoreUserList([])
    }
    
    const loadmoreHandler = () => {
      addPageNum()
      fetchSearchMoreUserList().finally(clearSearchLoading)
    }
    
    const loadmoreDebounceHandler = debounce(loadmoreHandler, BaseSelectUserFetchDebounceTime)
    
    const loadmoreDebounceImplHandler = () => {
      
      if (isLoadmoreNotDisabled.value) {
        setSearchLoading()
      }
      
      loadmoreDebounceHandler()
    }
    
    // 监听关键字变化，搜索用户列表
    watch(
      () => props.keyword,
      (newValue) => {
        
        // 清空当前搜索查看更多类型
        setCurrentSearchMoreType()
        // 清空当前搜索查看更多人员数据
        resetSearchMoreUserListAndPage()
        
        // 关键字为空时，清空之前的搜索结果列表数据
        if (isEmpty(newValue)) {
          
          setSearchUserListData({
            organizationUserList: [],
            serviceProviderUserList: []
          })
          
          return
        }
        
        // 这里设置加载状态，因为搜索人员列表方法加了 debounce，有延迟时间
        setSearchLoading()
        
        fetchSearchUserListDebounceHandler({ 
          keyword: newValue,
          showDelete: showDelete.value,
          showOrg: isShowSearchOrganizationUsers.value,
          showTagIfSpUser: showTagIfSpUser.value,
          showNoDistribute: showNoDistribute.value,
          authKey: isAuthKey.value,
          showSp: (
            isShowSearchServiceProviderUsers.value 
            && tabs.value.some(tab => isServiceProviderTab(tab))
          )
        })
        
      },
      {
        immediate: true
      }
    )
    
    return {
      organizationUserList,
      serviceProviderUserList,
      searchLoading,
      
      isShowNotDataView,
      isOrganizationUserListNotEmpty,
      isServiceProviderUserListNotEmpty,
      isCurrentSearchMoreTypeEmpty,
      isCurrentSearchMoreTypeNotEmpty,
      
      searchMoreUserList,
      backButtonName,
      
      isShowSearchMoreUserListNotDataView,
      isNotShowSearchMoreUserListNotDataView,
      isSearchOrganizationHasMore,
      isSearchSpHasMore,
      isLoadmoreDisabled,
      isShowSearchOrganizationUserList,
      isShowSearchServiceProviderUserList,
      
      setCurrentSearchMoreType,
      resetPageNum,
      fetchSearchMoreUserList,
      resetSearchMoreUserListAndPage,
      loadmoreDebounceImplHandler
    }
  },
  methods: {
    backSearchUserList() {
      this.setCurrentSearchMoreType()
    },
    /** 
    * @description 获取属性列表
    */
    getAttributes() {
      return {
        directives: [
          {
            name: 'loading',
            value: this.searchLoading
          }
        ]
      }
    },
    onOrganizationMoreClickHandler() {
      this.setCurrentSearchMoreType(BaseSelectUserSearchMoreTypeEnum.Organization)
      this.resetSearchMoreUserListAndPage()
      this.fetchSearchMoreUserList()
    },
    onServiceProviderMoreClickHandler() {
      this.setCurrentSearchMoreType(BaseSelectUserSearchMoreTypeEnum.ServiceProvider)
      this.resetSearchMoreUserListAndPage()
      this.fetchSearchMoreUserList()
    }
  },
  render(h: CreateElement) {
    
    const attrs = this.getAttributes()
    const className = BaseSelectUserComponentNameEnum.BaseSelectUserSearchUserPanel
    
    // 不处于加载状态时，且搜索结果为空时，显示暂无数据
    if (this.isShowNotDataView) {
      return (
        <div class={className} {...attrs}>
          <BaseSelectUserNoDataView />
        </div>
      )
    }
    
    return (
      <div class={className} {...attrs}>
        
        <div v-show={this.isCurrentSearchMoreTypeEmpty}>
          
          {this.isOrganizationUserListNotEmpty && (
            <BaseSelectUserSearchUserGroup 
              title={t('common.label.member')}
              is-show-more={this.isSearchOrganizationHasMore}
              onMore={this.onOrganizationMoreClickHandler}
            >
              <BaseSelectUserUserItems
                value={this.organizationUserList}
                is-multi={this.isMulti}
                is-search
              />
            </BaseSelectUserSearchUserGroup>
          )}
          
          {this.isServiceProviderUserListNotEmpty && (
            <BaseSelectUserSearchUserGroup 
              title={t('common.label.serviceProvider')}
              is-show-more={this.isSearchSpHasMore}
              onMore={this.onServiceProviderMoreClickHandler}
            >
              <BaseSelectUserUserItems
                value={this.serviceProviderUserList}
                is-multi={this.isMulti}
                is-search
              />
            </BaseSelectUserSearchUserGroup>
          )}
          
        </div>
        
        <div 
          class="base-select-user-search-more-user-panel" 
          v-show={this.isCurrentSearchMoreTypeNotEmpty}
        >
          
          <div>
            <BaseSelectUserBackButton 
              text={this.backButtonName}
              onBack={this.backSearchUserList}
            />
          </div>
          
          <div 
            class="base-select-user-height-100-percent" 
            v-show={this.isNotShowSearchMoreUserListNotDataView}
          >
            
            {/* start 无限滚动人员 */}
            <BaseSelectUserInfiniteScrollUser
              disabled={this.isLoadmoreDisabled}
              loadmore={this.loadmoreDebounceImplHandler}
            >
              {/* start 人员列表 */}
              <BaseSelectUserUserItems 
                value={this.searchMoreUserList} 
                is-multi={this.isMulti}
                is-search
              />
              {/* end 人员列表 */}
            </BaseSelectUserInfiniteScrollUser>
            {/* end 无限滚动人员 */}
            
          </div>
          
          {/* start 无数据显示 */}
          <BaseSelectUserNoDataView v-show={this.isShowSearchMoreUserListNotDataView} />
          {/* end 无数据显示 */}
          
        </div>
        
      </div>
    )
  }
})
